#pragma once

#include <QObject>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkConfiguration>
#include <QtNetwork/QNetworkReply>

enum HttpClientError
{
    HCE_OK = 0,
    HCE_HTTP_ERROR = 1,
    HCE_TIMEOUT = 2,
    HCE_INTERNAL_ERROR = 3,
};

class  HttpClient : public QObject
{
    Q_OBJECT

public:
    HttpClient(QObject *parent = Q_NULLPTR);
    ~HttpClient();

public:
    void setConfiguration(const QNetworkConfiguration& config)
    {
        accessManager.setConfiguration(config);
    }

    QNetworkReply* post(const QNetworkRequest& request, const QByteArray& data)
    {
        lazyDeleteNetworkReply();
        accessManager.clearConnectionCache();
        return reply = accessManager.post(request, data);
    }

    QNetworkReply* post(const QNetworkRequest& request, QHttpMultiPart *multiPart)
    {
        lazyDeleteNetworkReply();
        accessManager.clearConnectionCache();
        return reply = accessManager.post(request, multiPart);
    }

    QNetworkReply* put(const QNetworkRequest& request, const QByteArray& data)
    {
        lazyDeleteNetworkReply();
        accessManager.clearConnectionCache();
        return reply = accessManager.put(request, data);
    }

    QNetworkReply* put(const QNetworkRequest& request, QIODevice *data)
    {
        lazyDeleteNetworkReply();
        accessManager.clearConnectionCache();
        return reply = accessManager.put(request, data);
    }

    QNetworkReply* get(const QNetworkRequest& request)
    {
        lazyDeleteNetworkReply();
        accessManager.clearConnectionCache();
        return reply = accessManager.get(request);
    }

    QNetworkReply* head(const QNetworkRequest& request)
    {
        accessManager.clearConnectionCache();
        return reply = accessManager.head(request);
    }

    void setConnectTimeout(int milliseconds)
    {
        QNetworkConfiguration config = accessManager.configuration();
        config.setConnectTimeout(milliseconds);
        accessManager.setConfiguration(config);
    }

    QNetworkReply* getNetworkReply()
    {
        return reply;
    }

    static int syncPost(const QNetworkRequest& request, const QByteArray &param,
                        QNetworkReply::NetworkError &networkError, QByteArray &response,
                        int timeout = 6000);

    static int syncPost(const QNetworkRequest& request, QHttpMultiPart *multiPart,
                        QNetworkReply::NetworkError &networkError, QByteArray &response,
                        int timeout = 6000);

    static int syncGet(const QNetworkRequest& request,
                       QNetworkReply::NetworkError &networkError, QByteArray &response,
                       int timeout = 6000);

protected:
    void lazyDeleteNetworkReply()
    {
        if(reply)
        {
            reply->deleteLater();
            reply = Q_NULLPTR;
        }
    }

private:
    QNetworkAccessManager accessManager;
    QNetworkReply* reply = Q_NULLPTR;
};

